home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Franz PD / Franz PD Disk #054 (1990)(Amiga User Group Deutschland e.V.).zip / Franz PD Disk #054 (1990)(Amiga User Group Deutschland e.V.).adf / FastDiskII / Source / fd.c < prev    next >
C/C++ Source or Header  |  1989-07-02  |  22KB  |  955 lines

  1. /*
  2.  
  3.    FASTDISK by Thorsten Stolpmann
  4.    
  5.    Reworked for Lattice C 5.0.4. by Olli
  6.    
  7.    1.11.89:  first attempt to make it compile under lattice
  8.    2.11.89:  build in ARP-Support
  9.    3.11.89:  complete rework, gone cause to machine failure :-<
  10.    4.11.89:  complete rework, second attempt. add In' features
  11.    5.11.89:  do misc code optimizing
  12.          do more code optimizing
  13.          removed ALV-generation for "cback.o"
  14.          please remove the above sentence :-(
  15.                
  16. */
  17.  
  18. #define scmp !strnicmp
  19. #define error(); { closeall(); loop(); }
  20.  
  21. #include <proto/arp.h>
  22. #include <proto/exec.h>
  23. #include <proto/dos.h>
  24. #include <proto/icon.h>
  25. #include <exec/types.h>
  26. #include <exec/memory.h>
  27. #include <devices/trackdisk.h>
  28. #include <string.h>
  29.  
  30. /* Diskspezifische Daten */
  31.  
  32. #define NUMHEADS    2
  33. #define BLOCKSIZE    512
  34. #define SIZE        128
  35. #define NUM_ENTRIES    72
  36. #define NUMBLOCKS    1760 /* (NUMCYLC * NUMHEADS * NUMSECS) */
  37. #define ROOTBLOCK    880
  38. #define NUMLONGS    55
  39. #define SECS_PER_TRACK    22
  40.  
  41. /* Diskblockparameter */
  42.  
  43. #define TYPE        0
  44. #define HEADER_KEY    1
  45. #define HIGHEST_SEQ    2
  46. #define    SEQ_NUM        2
  47. #define BLOCK_COUNT    2
  48. #define    DATA_SIZE    3
  49. #define    FIRST_DATA    4
  50. #define    NEXT_DATA    4
  51. #define CHECKSUM    5
  52. #define DIR_HASHTAB    6
  53. #define FH_ENDLIST    6
  54. #define FH_BLOCKLIST    77
  55. #define BITMAPINDEX    79
  56. #define NAME        108
  57. #define CREATE_TICKS    123
  58. #define HASHCHAIN    124
  59. #define    PARENT        125
  60. #define EXTENSION    126
  61. #define SECONDARY_TYPE    127
  62. #define    BITMAP_CHECKSUM    0
  63. #define NAMEOFFSET    433
  64. #define NAMELENGTH    432
  65.  
  66. /*    Diskblock-Typ Definitionen     */
  67.  
  68. #define T_SHORT        2
  69. #define T_DATA        8
  70. #define T_LIST        16
  71. #define ST_ROOT        1
  72. #define ST_DIR        2
  73. #define ST_FILE        -3
  74.  
  75. #define EMPTY        (unsigned long*) 0
  76. #define BLOCKED        (unsigned long*) 0xFFFFFFFF
  77.  
  78. #define SOURCE        0
  79. #define DESTINATION    1
  80.  
  81.  
  82. /* Globale Variablen    */
  83.  
  84. extern struct Library        *ArpBase;
  85. struct IOExtTD        diskreq0,diskreq1,diskreq2;
  86. struct MsgPort        *diskport;
  87.  
  88. int    diskchangecount0,diskchangecount1;
  89. unsigned long    dirstack   [NUMBLOCKS];
  90. unsigned short    sectormap  [NUMBLOCKS];
  91. unsigned long    *buffermap [NUMBLOCKS];
  92. unsigned long    *readmap   [NUMBLOCKS];
  93. unsigned short    filestack  [NUMBLOCKS/2];
  94. unsigned char    trackmap   [160];
  95. unsigned short    dirstackptr ,filestackptr ,smptr;
  96. unsigned char    formatflag, fastloadflag;
  97. unsigned long    seccount, rootoff;
  98. unsigned long    *trackbuffer;
  99. unsigned long    *oldbuffer;
  100. unsigned short    sourcedrive ,destinationdrive;
  101. char        sourcedevice[5] = "DF0:";
  102. char        destdevice[5] = "DF1:";
  103. char         spb[34];
  104.  
  105. /* Prototypes */
  106.  
  107.  
  108. void moveblock(void);
  109. void sortfiles(void);
  110. void makefiles(void);
  111. void makeroot(void);
  112. void writeheaders(void);
  113. void writeblank(void);
  114. void writeboot(void);
  115. void closeall(void);
  116. void travel(int);
  117. int is_special(unsigned char *);
  118. int getfreesector(void);
  119. void dofile(unsigned long*);
  120. void makedirs(void);
  121. void init(void);
  122. void pushdir(int);
  123. int popdir(void);
  124. void pushfile(int);
  125. int popfile(void);
  126. void DoCheckSum(unsigned long*,int);
  127. void ReadSector(int,unsigned long*);
  128. unsigned long *GetSector(int);
  129. void formattrack(int);
  130. void WriteSector(int,unsigned long*);
  131. void PutSector(int,unsigned long*);
  132. unsigned long *allocbuffer(void);
  133. void releasebuffer(unsigned long *);
  134. void openall(void);
  135. void checkdisks(void);
  136. /*void error(void);*/
  137. void closeall(void);
  138.  
  139. void sprintf(char*,char*,);
  140.  
  141. void do_fast(int,int,int,int);
  142. void loop(void);
  143. void pmsg(char*,int);
  144.  
  145. void do_fast(dr1,dr2,fastdir,noformat)
  146. int dr1,dr2,fastdir,noformat;
  147. {
  148.     sourcedrive=dr1;
  149.     destinationdrive=dr2;
  150.     
  151.     sourcedevice[2] = (char) ('0' + (char) sourcedrive);
  152.     destdevice[2] = (char) ('0' + (char) destinationdrive);
  153.     fastloadflag=!fastdir;
  154.     formatflag=!noformat;
  155.     
  156.     pmsg("setting up",0);
  157.     openall ();
  158.     checkdisks();
  159.     init ();
  160.     pmsg("analyzing",0);
  161.     travel (ROOTBLOCK);
  162.     pmsg("moving blocks",0);
  163.     moveblock ();
  164.     pmsg("sorting files",0);
  165.     sortfiles ();
  166.     pmsg("making files",0);
  167.     makefiles ();
  168.     pmsg("making dirs",0);
  169.     makedirs ();
  170.     pmsg("making route",0);
  171.     makeroot ();
  172.     pmsg("writing headers",0);
  173.     writeheaders ();
  174.     pmsg("formating blanks",0);
  175.     writeblank();
  176.     pmsg("copying bootblock",0);
  177.     writeboot ();
  178.     pmsg("optimizing completed!",0);
  179.     closeall ();
  180. }
  181.  
  182. void travel(head)
  183. int head;
  184. {
  185.      unsigned long    *headbuffer,*workbuffer,*auxbuffer;
  186.     int sector,hc,i,count;
  187.     
  188.  
  189.     /*    Rekursives Durchlaufen des Directory-Trees in Zwischenordnung    */
  190.  
  191.     headbuffer = buffermap[head];
  192.     for (i=DIR_HASHTAB; i<=FH_BLOCKLIST; i++) {
  193.         sector=headbuffer[i];
  194.         if (sector) {
  195.             workbuffer = buffermap[sector] = GetSector(sector);
  196.             if ((workbuffer[TYPE] == T_SHORT) &&
  197.                 (workbuffer[SECONDARY_TYPE] == ST_DIR)) {
  198.                 if (fastloadflag) {
  199.                     sectormap[sector] = ROOTBLOCK+2+dirstackptr;
  200.                 } else {
  201.                     sectormap[sector] = smptr++;
  202.                 }
  203.                 pushdir(sector);
  204.                 travel(sector);
  205.             }
  206.             else {
  207.                 sectormap[sector] = smptr++;
  208.                 pushfile(sector);
  209.  
  210.                     /*    Existieren File List Blocks ?    */
  211.  
  212.                 auxbuffer = buffermap[sector];
  213.                 count = workbuffer[HIGHEST_SEQ];
  214.                 while (auxbuffer[EXTENSION]) {
  215.                     sector = auxbuffer[EXTENSION];
  216.                     auxbuffer = buffermap[sector] = GetSector(sector);
  217.                     count += auxbuffer[BLOCK_COUNT];
  218.                     sectormap[sector] = smptr++;
  219.                 }
  220.  
  221.                 /*    Ist es ein .info-File?    */
  222.  
  223.                 if (is_special(workbuffer)) {
  224.                     sectormap[workbuffer[FIRST_DATA]] = smptr;
  225.                     smptr += count;
  226.                 }
  227.             }
  228.  
  229.             /* Weitere Header-Blocks in der Hashchain ?     */
  230.  
  231.             hc=workbuffer[HASHCHAIN];
  232.             while (hc) {
  233.                 workbuffer = buffermap[hc] = GetSector(hc);
  234.                 if ((workbuffer[TYPE] == T_SHORT) &&
  235.                     (workbuffer[SECONDARY_TYPE] == ST_DIR)) {
  236.                     sectormap[hc] = ROOTBLOCK+2+dirstackptr;
  237.                     if (fastloadflag) {
  238.                         sectormap[hc] = ROOTBLOCK+2+dirstackptr;
  239.                     } else {
  240.                         sectormap[hc] = smptr++;
  241.                     }
  242.                     pushdir(hc);
  243.                     travel(hc);
  244.                 }
  245.                 else {
  246.                     sectormap[hc]=smptr++;
  247.                     pushfile(hc);
  248.  
  249.                     /*    Existieren File List Blocks ?    */
  250.  
  251.                     auxbuffer = buffermap[hc];
  252.                     count = workbuffer[HIGHEST_SEQ];
  253.                     while (auxbuffer[EXTENSION]) {
  254.                         sector = auxbuffer[EXTENSION];
  255.                         auxbuffer = buffermap[sector] = GetSector(sector);
  256.                         count += auxbuffer[BLOCK_COUNT];
  257.                         sectormap[sector] = smptr++;
  258.                     }
  259.  
  260.                     /*    Ist es ein .info-File ?        */
  261.  
  262.                     if (is_special(workbuffer)) {
  263.                         sectormap[workbuffer[FIRST_DATA]] = smptr;
  264.                         smptr += count;
  265.                     }
  266.                 }
  267.                 hc=workbuffer[HASHCHAIN];
  268.             }
  269.         }
  270.     }
  271. }
  272.  
  273. void moveblock()
  274. {
  275.     int sector,dest,diff;
  276.     
  277.     /*    Zentriert die Header-Blocks auf der Diskette    */
  278.  
  279.     if ((diff = (smptr-881)/SECS_PER_TRACK) > 2) {
  280.         diff = (((diff/2)+1) * SECS_PER_TRACK) - 2;
  281.     } else {
  282.         diff = 0;
  283.     }
  284.     if (fastloadflag) {
  285.         rootoff += dirstackptr;
  286.         diff -= dirstackptr;
  287.     }
  288.  
  289.     for (sector=2; sector < NUMBLOCKS; ++sector) {
  290.         dest = sectormap[sector];
  291.         if ((dest)
  292.          && (dest != 880)
  293.          && (dest != 881)
  294.           && !((fastloadflag) &&
  295.               (buffermap[sector][SECONDARY_TYPE] == ST_DIR))) {
  296.             if ((dest >= 882) && (dest-diff < ROOTBLOCK+rootoff)) {
  297.                 sectormap[sector] -= (ULONG) (diff+rootoff);
  298.             } else {
  299.                 sectormap[sector] -= (ULONG) diff;                    }
  300.         }
  301.     }
  302.     seccount = (ULONG) ROOTBLOCK - diff;
  303. }
  304.  
  305. void sortfiles()
  306. {
  307.      int    file,count,top,temp;
  308.     
  309.     /* Erst die .info-Files kopieren */
  310.  
  311.     top = filestackptr-1;
  312.     for (file = 0; file < top;file++) {
  313.         if (is_special(buffermap[filestack[file]])) {
  314.             temp = filestack[file];
  315.             for (count=file; count < top; count++) {
  316.                 filestack[count] = filestack[count+1];
  317.             }
  318.             filestack[top--] = temp;
  319.             file--;
  320.         }
  321.     }
  322. }
  323.  
  324.  
  325. int is_special(buffer)
  326.  unsigned char    *buffer;
  327. {
  328.  
  329.     /* Diese Files werden direkt hinter ihrem Headerblock abgelegt */
  330.  
  331.     pmsg(buffer+NAMEOFFSET,0);
  332.     
  333.     if (fastloadflag) {
  334.         return (1);
  335.     }
  336.  
  337.     if (scmp(buffer+NAMEOFFSET+buffer[NAMELENGTH]-5,".INFO",5)) {
  338.         return (1);
  339.     }
  340.  
  341.     if (scmp(buffer+NAMEOFFSET,"SYSTEM-CONFIGURATION",20)) {
  342.         return (1);
  343.     }
  344.  
  345.     if (scmp(buffer+NAMEOFFSET,"STARTUP-SEQUENCE",16)) {
  346.         return (1);
  347.     }
  348.     return (0);
  349. }
  350.  
  351. int getfreesector()
  352. {
  353.  
  354.     /* Liefert naechsten freier Sector auf der Diskette */
  355.  
  356.     if (seccount == 2) {
  357.         return (seccount = NUMBLOCKS-1);
  358.     } else {
  359.         return (--seccount);
  360.     }
  361. }
  362.  
  363. void makefiles()
  364. {
  365.      int    file;
  366.  
  367.     /* kopiert alle File-Datenblocks auf die Zieldiskette.
  368.        Die neuen Sectorpositionen werden in den Headerblocks korrigiert. */
  369.  
  370.     while (file = popfile()) {
  371.         dofile(buffermap[file]);
  372.     }
  373. }
  374.  
  375. void dofile(headbuffer)
  376.  unsigned long    *headbuffer;
  377. {
  378.      unsigned long    *workbuffer;
  379.      int sector,next_sector,more_to_come;
  380.  
  381.     if (headbuffer[FIRST_DATA]) {
  382.         workbuffer = GetSector(headbuffer[FIRST_DATA]);
  383.         if (is_special(headbuffer)) {
  384.             sector = sectormap[headbuffer[FIRST_DATA]];
  385.             if (sector == ROOTBLOCK) {
  386.                 sector += rootoff;
  387.             }
  388.         } else {
  389.             sector = getfreesector();
  390.         }
  391.         sectormap[headbuffer[FIRST_DATA]] = sector;
  392.         do {
  393.             workbuffer[HEADER_KEY]=sectormap[headbuffer[HEADER_KEY]];
  394.             more_to_come = workbuffer[NEXT_DATA];
  395.             if (more_to_come) {
  396.                 if (is_special(headbuffer)) {
  397.                     next_sector = sector + 1;
  398.                     if (next_sector == ROOTBLOCK) {
  399.                         next_sector += rootoff;
  400.                     }
  401.                 } else {
  402.                     next_sector = getfreesector();
  403.                 }
  404.                 workbuffer[NEXT_DATA] = next_sector;
  405.             }
  406.             DoCheckSum(workbuffer,CHECKSUM);
  407.             PutSector(sector,workbuffer);
  408.             if (more_to_come) {
  409.                 workbuffer = GetSector(more_to_come);
  410.                 sector = sectormap[more_to_come] = next_sector;
  411.             }
  412.         } while (more_to_come);
  413.     }
  414.         /*    Aenderungen in File Header & File List Blocks    */
  415.  
  416.     do {
  417.         more_to_come = headbuffer[EXTENSION];
  418.         sector = FH_BLOCKLIST;
  419.         while (sector >= FH_ENDLIST) {
  420.             headbuffer[sector--]=sectormap[headbuffer[sector]];
  421.         }
  422.         headbuffer[PARENT]     = sectormap[headbuffer[PARENT]];
  423.         headbuffer[HEADER_KEY] = sectormap[headbuffer[HEADER_KEY]];
  424.         headbuffer[FIRST_DATA] = sectormap[headbuffer[FIRST_DATA]];
  425.         headbuffer[HASHCHAIN]  = sectormap[headbuffer[HASHCHAIN]];
  426.         headbuffer[EXTENSION]  = sectormap[headbuffer[EXTENSION]];
  427.         DoCheckSum(headbuffer,CHECKSUM);
  428.         if (more_to_come) {
  429.             headbuffer = buffermap[more_to_come];
  430.         }
  431.     } while (more_to_come);
  432. }
  433.  
  434. void makedirs()
  435. {
  436.      unsigned long    *headbuffer;
  437.     int dir,sector;
  438.     
  439.     /* Aenderungen in den Directory-Header Blocks */
  440.  
  441.     while (dir = popdir()) {
  442.         headbuffer = buffermap[dir];
  443.         for ( sector = FH_BLOCKLIST;
  444.               sector >= FH_ENDLIST;
  445.               --sector) {
  446.             if (headbuffer[sector]) {
  447.                 headbuffer[sector]=sectormap[headbuffer[sector]];
  448.             }
  449.         }
  450.         headbuffer[PARENT]     = sectormap[headbuffer[PARENT]];
  451.         headbuffer[HEADER_KEY] = sectormap[headbuffer[HEADER_KEY]];
  452.         headbuffer[HASHCHAIN]  = sectormap[headbuffer[HASHCHAIN]];
  453.         headbuffer[EXTENSION]  = sectormap[headbuffer[EXTENSION]];
  454.         DoCheckSum(headbuffer,CHECKSUM);
  455.     }
  456. }        
  457.  
  458. void makeroot()
  459. {
  460.      unsigned long    *headbuffer,*workbuffer;
  461.     int sector,bmsector,mask,offset,count;
  462.     
  463.     workbuffer = allocbuffer();
  464.     headbuffer = buffermap[ROOTBLOCK];
  465.  
  466.     /* Aenderungen im Rootblock */
  467.  
  468.     bmsector = sectormap[headbuffer[BITMAPINDEX]];
  469.     for ( sector = FH_BLOCKLIST; sector >= FH_ENDLIST; --sector) {
  470.         if (headbuffer[sector]) {
  471.             headbuffer[sector]=sectormap[headbuffer[sector]];
  472.         }
  473.     }
  474.     headbuffer[BITMAPINDEX] = bmsector;
  475.     headbuffer[CREATE_TICKS] += 1;    /* Wichtig ! Hiermit wird gesichert, */
  476.                     /* dass AmigaDOS Quell- und Zieldisk */
  477.                     /* unterscheiden kann. */
  478.     DoCheckSum(headbuffer,CHECKSUM);
  479.  
  480.     /* Neuen Bit-Map Sector erstellen */
  481.  
  482.     for (count=1; count <= NUMLONGS; ++count) {
  483.         workbuffer[count] = 0xFFFFFFFF;
  484.     }
  485.  
  486.     for (count = 2; count < NUMBLOCKS; ++count) {
  487.         sector = sectormap[count];
  488.         if (sector) {
  489.             offset = 1 + ((sector-2)/32);
  490.             mask   = (ULONG) 1 << ((sector-2) & 0x1f);
  491.             workbuffer[offset] -= (ULONG) mask;
  492.         }
  493.     }
  494.     DoCheckSum(workbuffer,BITMAP_CHECKSUM);
  495.     PutSector(bmsector,workbuffer);
  496. }
  497.  
  498. void writeheaders()
  499. {
  500.     int    buffer;
  501.  
  502.     /* Alle Header-Blocks werden auf Zieldisk geschrieben */
  503.  
  504.     for (buffer=0; buffer<NUMBLOCKS; ++buffer) {
  505.         dirstack[buffer] = NULL;
  506.     }
  507.  
  508.     for (buffer = 2; buffer<NUMBLOCKS; ++buffer) {
  509.         if (buffermap[buffer]) {
  510.             dirstack[sectormap[buffer]] = (ULONG) buffermap[buffer];
  511.             buffermap[buffer] = NULL;
  512.         }
  513.     }
  514.  
  515.     for (buffer = 0; buffer<NUMBLOCKS; ++buffer) {
  516.         if (dirstack[buffer]) {
  517.             PutSector((ULONG) buffer,dirstack[buffer]);
  518.         }
  519.     }
  520.     PutSector(NULL,NULL);
  521. }
  522.  
  523. void writeblank()
  524. {
  525.     int    i;
  526.  
  527.     /* Formatiert nicht belegte Tracks auf der Zieldisk */
  528.  
  529.     if (formatflag) {
  530.         for (i=0; i < 160; i++) {
  531.             if ( !(trackmap[i])) {
  532.                 formattrack(i);
  533.                 WaitIO(&diskreq2);
  534.                 trackmap[i]=1;
  535.             }
  536.         }
  537.     }
  538. }
  539.  
  540. void writeboot()
  541. {
  542.      unsigned long *workbuffer;
  543.  
  544.     /* Bootsectoren uebertragen */
  545.  
  546.     workbuffer = allocbuffer();
  547.     ReadSector (0L,workbuffer);
  548.     WriteSector(0L,workbuffer);
  549.     WaitIO(&diskreq1);
  550.     ReadSector (1L,workbuffer);
  551.     WriteSector(1L,workbuffer);
  552.     WaitIO(&diskreq1);
  553.     diskreq1 . iotd_Req.io_Command = ETD_UPDATE;
  554.     diskreq1 . iotd_Count        = diskchangecount1;
  555.     DoIO (&diskreq1);
  556.     releasebuffer(workbuffer);
  557. }
  558.  
  559. void init()
  560. {
  561.      unsigned long    *headbuffer,*workbuffer;
  562.      unsigned long    count,offset,mask;
  563.  
  564.     
  565.  
  566.     /* Feldinitialisierungen */
  567.  
  568.     for (count=0L; count < NUMBLOCKS; ++count) {
  569.         sectormap [count] = NULL;
  570.         buffermap [count] = NULL;
  571.         dirstack  [count] = NULL;
  572.         readmap   [count] = EMPTY;
  573.     }
  574.     sectormap[0] = 0L;
  575.     sectormap[1] = 1L;
  576.  
  577.     /* Trackbuffer */
  578.  
  579.     for (count=0; count <= 160; count++) {
  580.         trackmap[count] = 0;
  581.     }
  582.  
  583.     if ( !(trackbuffer = AllocMem(NUMSECS * BLOCKSIZE, MEMF_CHIP | MEMF_CLEAR))) {
  584.         pmsg("can't allocate trackbuffer!",1);
  585.         error();
  586.     }
  587.  
  588.     /* Rootblock laden */
  589.  
  590.     smptr = ROOTBLOCK;
  591.     headbuffer = buffermap[ROOTBLOCK] = GetSector(ROOTBLOCK);
  592.     sectormap[ROOTBLOCK] = smptr++;
  593.     sectormap[headbuffer[BITMAPINDEX]] = smptr++;
  594.  
  595.     /* Markieren aller nicht belegter Bloecke (BAM-Selection) */
  596.  
  597.     workbuffer = GetSector(headbuffer[BITMAPINDEX]);
  598.     for (count = 2L; count < NUMBLOCKS; ++count) {
  599.         offset = 1L + ((count-2L)/32L);
  600.         mask   = 1L << ((count-2L) & 0x1fL);
  601.         if (workbuffer[offset] & mask) {
  602.             if (readmap[count]) {
  603.                 releasebuffer(readmap[count]);
  604.             }
  605.             readmap[count] = BLOCKED;
  606.         }
  607.     }
  608.     readmap[ROOTBLOCK] = readmap[headbuffer[BITMAPINDEX]] = BLOCKED;
  609.     readmap[0] = readmap[1] = BLOCKED;
  610.     releasebuffer(workbuffer);
  611. }
  612.  
  613. void pushdir(sector)
  614.  int    sector;
  615. {
  616.     dirstack[dirstackptr++] = sector;
  617. }
  618.  
  619. int popdir()
  620. {
  621.     if ((dirstackptr) == 0)
  622.         return (NULL);
  623.     else
  624.         return (dirstack[--dirstackptr]);
  625. }
  626.  
  627. void pushfile(sector)
  628. int    sector;
  629. {
  630.     filestack[filestackptr++] = sector;
  631. }
  632.  
  633. int popfile()
  634. {
  635.     if ((filestackptr) == 0)
  636.         return (NULL);
  637.     else
  638.         return (filestack[--filestackptr]);
  639. }
  640.  
  641. void DoCheckSum(buffer,pos)
  642.  unsigned long    *buffer;
  643.  int pos;
  644. {
  645.     int count;
  646.       unsigned long    checksum;
  647.  
  648.     /* CheckSum fuer normale und Bit-Map Blocks errechnen */
  649.  
  650.     buffer[pos] = checksum = NULL;
  651.     for (count=0; count < SIZE; ++count) {
  652.         checksum += (unsigned long) buffer[count];
  653.     }
  654.     buffer[pos] -= (unsigned long) checksum;
  655. }
  656.  
  657. void ReadSector (sector,buffer)
  658. int sector;
  659.  unsigned long *buffer;
  660. {
  661.     /* Laedt einen Sector von der Quell-Diskette */
  662.  
  663.     diskreq0 . iotd_Req.io_Length     = BLOCKSIZE;      
  664.     diskreq0 . iotd_Req.io_Data     = (APTR) buffer;    
  665.     diskreq0 . iotd_Req.io_Command = ETD_READ;
  666.     diskreq0 . iotd_Count         = diskchangecount0;
  667.     diskreq0 . iotd_Req.io_Offset     = sector*512;
  668.     DoIO (&diskreq0);
  669.     if (diskreq0 . iotd_Req.io_Error) {
  670.         sprintf(spb,"DF%ld: readerror %ld on %ld!",(int)sourcedrive,(int)diskreq0.iotd_Req.io_Error,(int)sector);
  671.         pmsg(spb,1);
  672.         error();
  673.     }
  674. }
  675.  
  676. unsigned long *GetSector(sector)
  677.  int    sector;
  678. {
  679.      unsigned long    *workbuffer,*temp;
  680.      int    track,sec;
  681.  
  682.     /* Holt einen Sector von der Quell-Diskette oder */
  683.     /* liefert den entsprechenden Buffer. */
  684.  
  685.     if (sector >= NUMBLOCKS) {
  686.         sprintf(spb,"DF%ld: illegal sector %ld!",(int)sourcedrive,(int)sector);
  687.         pmsg(spb,1);
  688.         error();
  689.     }
  690.     if (readmap[sector]) {
  691.         if (readmap[sector] == BLOCKED) {
  692.             sprintf(spb,"DF%ld: double reference to %ld!",(int)sourcedrive,(int)sector);
  693.             pmsg(spb,1);
  694.             error();
  695.         } else {
  696.             temp = readmap[sector];
  697.             readmap[sector] = BLOCKED;
  698.             return (temp);
  699.         }
  700.     } else {
  701.         workbuffer = allocbuffer();
  702.         ReadSector (sector,workbuffer);
  703.         readmap[sector] = BLOCKED;
  704.         track = sector / SECS_PER_TRACK;
  705.         for (sec=track*SECS_PER_TRACK; sec < (track+1)*SECS_PER_TRACK; sec++) {
  706.             if (readmap[sec] == EMPTY) {
  707.                 if (readmap[sec] = allocbuffer()) {
  708.                     ReadSector(sec,readmap[sec]);
  709.                 } else {
  710.                     break;
  711.                 }
  712.             }
  713.         }
  714.         return (workbuffer);
  715.     }
  716. }
  717.  
  718. void formattrack(track)
  719.  int track;
  720. {
  721.  
  722.     /* Formatiert einen Track auf der Zieldiskette */
  723.  
  724.     
  725.     diskreq2 . iotd_Req.io_Length    = NUMSECS * BLOCKSIZE;      
  726.     diskreq2 . iotd_Req.io_Data    = (APTR) trackbuffer;    
  727.     diskreq2 . iotd_Req.io_Command = TD_FORMAT;
  728.     diskreq2 . iotd_Count        = diskchangecount1;
  729.     diskreq2 . iotd_Req.io_Offset    = track * (NUMSECS * BLOCKSIZE);
  730.     SendIO (&diskreq2);
  731.     if (diskreq1 . iotd_Req.io_Error) {
  732.         sprintf(spb,"DF%ld: formaterror %ld on cyl %ld!",(int)destinationdrive,(int)diskreq2.iotd_Req.io_Error,(int)track/2);
  733.         error();
  734.     }
  735. }
  736.  
  737. void WriteSector(sector,buffer)
  738.  int sector;
  739.  unsigned long *buffer;
  740. {
  741.      short int    track;
  742.  
  743.     /* Falls noch nicht geschehen, formatieren des Ziel-Tracks */
  744.  
  745.     track = (sector / 11);
  746.     if ( (formatflag) && !(trackmap[track])) {
  747.         formattrack(track);
  748.         trackmap[track] = 1;
  749.     }
  750.  
  751.     /* Schreibt einen Sector auf die Ziel-Diskette */
  752.  
  753.     diskreq1 . iotd_Req.io_Length    = BLOCKSIZE;      
  754.     diskreq1 . iotd_Req.io_Data    = (APTR) buffer;    
  755.     diskreq1 . iotd_Req.io_Command = ETD_WRITE;
  756.     diskreq1 . iotd_Count        = diskchangecount1;
  757.     diskreq1 . iotd_Req.io_Offset    = sector*512;
  758.     SendIO (&diskreq1); /* Asynchroner Schreibzugriff */
  759. }
  760.  
  761. void PutSector(sector,buffer)
  762.  int sector;
  763.  unsigned long *buffer;
  764. {
  765.  
  766.     /* Schreibt Sector auf Zieldisk und deallociert den Buffer */
  767.  
  768.     if (oldbuffer) {
  769.         WaitIO(&diskreq1); /* Warten auf das Ende des letzten Schreibzugriffs */
  770.         if (diskreq1 . iotd_Req.io_Error) {
  771.             sprintf(spb,"DF%ld: write error %ld on %ld!",(int)destinationdrive,(int)diskreq1.iotd_Req.io_Error,(int)sector);
  772.             pmsg(spb,1);
  773.             error();
  774.         }
  775.         releasebuffer(oldbuffer);
  776.     }
  777.     if (oldbuffer = buffer) {
  778.         WriteSector(sector, buffer);
  779.     }
  780. }
  781.  
  782. unsigned long *allocbuffer()
  783. {
  784.      unsigned long    *buffer;
  785.      int sec;
  786.  
  787.     /* Allociert 512 Byte Chip-Memory als Sector-Buffer */
  788.     /* Falls kein Chip-Mem mehr vorhanden ist, wird ein */
  789.     /* bestehender, nicht unbedingt benoetigter Sector  */
  790.     /* deallociert.                     */
  791.  
  792.     buffer = AllocMem((long) BLOCKSIZE, MEMF_CHIP);
  793.     if (buffer == NULL) {
  794.         for (sec=2; sec<NUMBLOCKS; sec++) {
  795.             if ((readmap[sec]) && 
  796.                 (readmap[sec] != BLOCKED) &&
  797.                 (readmap[sec][TYPE] == T_DATA)) {
  798.                 buffer = readmap[sec];
  799.                 readmap[sec] = EMPTY;
  800.                 break;
  801.             }
  802.         }
  803.         if (sec == NUMBLOCKS) {
  804.             pmsg("out of CHIP-mem!",1);
  805.             error();
  806.         }
  807.     }
  808.     return (buffer);
  809. }
  810.  
  811. void releasebuffer(buffer)
  812.  unsigned long *buffer;
  813. {
  814.  
  815.     /* Deallociert einen 512-Byte Buffer */
  816.  
  817.     if (buffer) {
  818.         FreeMem(buffer, (long) BLOCKSIZE);
  819.     }
  820. }
  821.  
  822. void openall()
  823. {
  824.     int    err;
  825.  
  826.     /* Oeffnen der Disk-Devices */
  827.  
  828.     smptr=ROOTBLOCK;
  829.     rootoff=2;
  830.     oldbuffer=trackbuffer=dirstackptr=filestackptr=0;
  831.     diskreq0.iotd_Req.io_Device=0;
  832.     diskreq1.iotd_Req.io_Device=0;
  833.     diskreq2.iotd_Req.io_Device=0;
  834.  
  835.     if ( !(diskport = CreatePort (NULL, NULL))) {
  836.         pmsg("can't create MsgPort!",1);
  837.         error();
  838.     }
  839.  
  840.     diskreq0.iotd_Req.io_Message.mn_ReplyPort=diskport;
  841.     diskreq1.iotd_Req.io_Message.mn_ReplyPort=diskport;
  842.     diskreq2.iotd_Req.io_Message.mn_ReplyPort=diskport;
  843.     
  844.     if (err = OpenDevice (TD_NAME, sourcedrive, &diskreq0, NULL)) {
  845.         sprintf(spb,"DF%ld: openerror %ld!",(int)sourcedrive,(int)err);
  846.         pmsg(spb,1);
  847.         diskreq0.iotd_Req.io_Device=0;
  848.         error();
  849.     }
  850.  
  851.     if (err = OpenDevice (TD_NAME, destinationdrive, &diskreq1, NULL)) {
  852.         sprintf(spb,"DF%ld: openerror %ld!",(int)destinationdrive,(int)err);
  853.         pmsg(spb,1);
  854.         diskreq1.iotd_Req.io_Device=0;
  855.         error();
  856.     }
  857.  
  858.     if (err = OpenDevice (TD_NAME, destinationdrive, &diskreq2, NULL)) {
  859.         sprintf(spb,"DF%ld: openerror %ld!",(int)destinationdrive,(int)err);
  860.         pmsg(spb,1);
  861.         diskreq2.iotd_Req.io_Device=0;
  862.         error();
  863.     }
  864.  
  865.     /* Disk-Validation abstellen */
  866.  
  867.     /* ARP by Olli */
  868.     
  869.     err=-1;
  870.  
  871.     SendPacket(ACTION_INHIBIT,&err,DeviceProc(destdevice));
  872.     SendPacket(ACTION_INHIBIT,&err,DeviceProc(sourcedevice));
  873.     
  874. }
  875.  
  876. void checkdisks()
  877. {
  878.     diskreq0 . iotd_Req.io_Command = TD_CHANGESTATE;
  879.     DoIO (&diskreq0);
  880.     if (diskreq0 . iotd_Req.io_Actual) {
  881.         sprintf(spb,"no disk in DF%ld:!",(int)sourcedrive);
  882.         pmsg(spb,1);
  883.         error();
  884.     }
  885.  
  886.     diskreq1 . iotd_Req.io_Command = TD_CHANGESTATE;
  887.     DoIO (&diskreq1);
  888.     if (diskreq1 . iotd_Req.io_Actual) {
  889.         sprintf(spb,"no disk in DF%ld:!",(int)destinationdrive);
  890.         pmsg(spb,1);
  891.         error();
  892.     }
  893.  
  894.     diskreq1 . iotd_Req.io_Command = TD_PROTSTATUS;
  895.     DoIO (&diskreq1);
  896.     if (diskreq1 . iotd_Req.io_Actual) {
  897.         sprintf(spb,"DF%ld: write-protect on!",(int)destinationdrive);
  898.         pmsg(spb,1);
  899.         error();
  900.     }
  901.  
  902.     diskreq0 . iotd_Req.io_Command = TD_CHANGENUM;
  903.     DoIO (&diskreq0);
  904.     diskchangecount0 = diskreq0 . iotd_Req.io_Actual;
  905.  
  906.     diskreq1 . iotd_Req.io_Command = TD_CHANGENUM;
  907.     DoIO (&diskreq1);
  908.     diskchangecount1 = diskreq1 . iotd_Req.io_Actual;
  909.  
  910. }
  911.  
  912. /*void error()
  913. {
  914.     closeall();
  915.     loop();
  916. }*/
  917.  
  918. void closeall()
  919. {
  920.     int    count;
  921.  
  922.     /* Schliessen der Disk-Devices */
  923.     /* Deallocieren der Buffer     */
  924.     /* Schliessen der Library      */
  925.  
  926.     if (oldbuffer) {
  927.         releasebuffer(oldbuffer);
  928.     }
  929.  
  930.     for (count = NULL; count<NUMBLOCKS; ++count) {
  931.         if (buffermap[count]) {
  932.             releasebuffer(buffermap[count]);
  933.         }
  934.         if ((readmap[count]) && (readmap[count] != BLOCKED)) {
  935.             releasebuffer(readmap[count]);
  936.         } 
  937.     }
  938.  
  939.     if (trackbuffer) {
  940.         FreeMem(trackbuffer,NUMSECS * BLOCKSIZE);
  941.     }
  942.  
  943.     if (diskreq0.iotd_Req.io_Device) CloseDevice(&diskreq0);
  944.     if (diskreq1.iotd_Req.io_Device) {
  945.         CloseDevice(&diskreq1);
  946.         SendPacket(ACTION_INHIBIT,0,DeviceProc(destdevice));
  947.         SendPacket(ACTION_INHIBIT,0,DeviceProc(sourcedevice));
  948.     }
  949.     if (diskreq2.iotd_Req.io_Device) CloseDevice(&diskreq2);
  950.  
  951.     if (diskport) {
  952.         DeletePort (diskport);
  953.     }
  954. }
  955.